package cn.kaguyaever.dao.impl;

import cn.kaguyaever.utils.JdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

public abstract class BaseDao<T> {
    private Class<T> type = null;
    //获取泛型类型
    public BaseDao(){
        //获取子类类型
        Class clazz = this.getClass();
        //获取父类的带泛型的类型
        ParameterizedType paramType = (ParameterizedType)clazz.getGenericSuperclass();
        Type[] typeArguments = paramType.getActualTypeArguments();
        //获取具体的泛型类型
        type = (Class<T>)typeArguments[0];
    }
    //使用DbUtils操作数据库
    private QueryRunner queryRunner = new QueryRunner();
    //update()执行增删改查，返回-1说明执行失败，否则返回影响的行数
    public int update(String sql,Object... args){
        Connection connection = JdbcUtils.getConnection();
        try {
            return queryRunner.update(connection,sql,args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            JdbcUtils.close(connection);
        }
        return -1;
    }
    //queryForOne()查询返回一个javaBean
    public T queryForOne(String sql,Object... args) {
        Connection connection = JdbcUtils.getConnection();
        try {
            return  queryRunner.query(connection, sql, new BeanHandler<T>(type), args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            JdbcUtils.close(connection);
        }
        return null;
    }

    public List<T> queryForList(String sql, Object... args){
        Connection connection = JdbcUtils.getConnection();
        try {
            return queryRunner.query(connection,sql,new BeanListHandler<T>(type),args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            JdbcUtils.close(connection);
        }
        return null;
    }
    //queryForSingleValue()返回一行一列
    public <E> E queryForSingleValue(String sql,Object... args){
        Connection connection = JdbcUtils.getConnection();
        try {
           return (E)queryRunner.query(connection,sql,new ScalarHandler(),args);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            JdbcUtils.close(connection);
        }
        return null;
    }
}
